using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Xml;
using System.Drawing;
using MacomberMap.Common.User_Interfaces.Components;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using MacomberMap.Common.Components;
using MacomberMap.Common.Types;
using MacomberMap.Common.Database_Interface;

namespace MacomberMap.Common.User_Interfaces.One_Lines.Elements
{
    /// <summary>
    /// This class handles the components for a breaker
    /// </summary>
    public class MM_OneLine_Breaker: MM_OneLine_Element
    {
        #region Variable declarations
        private CheckState _Opened = CheckState.Indeterminate;
        /// <summary>Whether the breaker is opened</summary>
        [Category("MacomberMap"), Description("Whether the breaker is opened"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]        
        public CheckState Opened
        {
            get { return _Opened; }
            set { _Opened = value; this.Invalidate(); }
        }

        private CheckState _ScadaOpened = CheckState.Indeterminate;
        /// <summary>Whether SCADA reports the breaker as opened</summary>
        [Category("MacomberMap"), Description("Whether SCADA reports the breaker as opened"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]                
        public CheckState ScadaOpened
        {
            get { return _ScadaOpened; }
            set { _ScadaOpened = value; this.Invalidate(); }
        }

        /// <summary>"Whether the breaker has a synchroscope attached to it.</summary>
        [Category("Element"),Description("Whether the breaker has a synchroscope attached to it.")]
        public bool HasSynchroscope
        {
            get { return _HasSynchroscope; }
            set { _HasSynchroscope = value; }
        }
        private bool _HasSynchroscope = false;
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new breaker
        /// </summary>
        /// <param name="DisplayParameters"></param>
        public MM_OneLine_Breaker(MM_OneLine_Display DisplayParameters)
            : base(DisplayParameters)
        {
        }

        /// <summary>
        /// Initialize a new viewable breaker
        /// </summary>
        /// <param name="ElemConfig">The Xml configuration for the line</param>
        /// <param name="DisplayParameters">The display parameters for the line</param>
        /// <param name="DbConnection">The database connection</param>
        public MM_OneLine_Breaker(XmlElement ElemConfig, MM_OneLine_Display DisplayParameters, MM_Database DbConnection)
            : base(ElemConfig, DisplayParameters, DbConnection)
        {
            //Retrieve our arrow direction from the 
            Orientation = ParseOrientation(ElemConfig.Attributes["Orientation"].Value);           
        }

        /// <summary>
        /// Initialize a new viewable breaker
        /// </summary>
        /// <param name="SelectedElement">The CIM element upon which the line is based</param>
        /// <param name="DisplayParameters">The display parameters</param>
        /// <param name="Orientation">The orientation of the breaker</param>
        public MM_OneLine_Breaker(MM_Element SelectedElement, MM_OneLine_Display DisplayParameters, MM_OneLine_Element.enumOrientations Orientation)
            : base(SelectedElement, DisplayParameters, Orientation)
        {                            
        }
        #endregion

        #region Rendering
        /// <summary>
        /// Draw the image for the breaker
        /// </summary>
        /// <param name="g"></param>
        public override void DrawImage(Graphics g)
        {
            //Now, draw the center box with state
            Rectangle DrawRect = new Rectangle(2, 2, Width - 5, Width - 5);
            Color DrawColor = KVLevel == null ? Color.Red : KVLevel.Energized.ForeColor;
            Point Center = CenterRect(DisplayRectangle);

            using (Font DrawFont = new Font("Arial", 13, FontStyle.Bold))
            using (SolidBrush BackBrush = new SolidBrush(BackColor))
            using (SolidBrush ForeBrush = new SolidBrush(DrawColor))
            using (Pen DrawPen = new Pen(DrawColor))
            {
                if (_Opened == CheckState.Checked)
                {
                    g.FillRectangle(BackBrush, DrawRect);
                    g.DrawRectangle(DrawPen, DrawRect);
                    g.DrawString("O", DrawFont, ForeBrush, DrawRect, CenterFormat);
                }
                else if (_Opened == CheckState.Unchecked)
                {
                    g.FillRectangle(ForeBrush, DrawRect);
                    g.DrawString("C", DrawFont, BackBrush, DrawRect, CenterFormat);
                }
                else if (_Opened == CheckState.Indeterminate)
                {
                    g.FillRectangle(BackBrush, DrawRect);
                    using (HatchBrush hb = new HatchBrush(HatchStyle.Percent50, Color.FromArgb(64, KVLevel == null ? Color.Red : KVLevel.Energized.ForeColor), Color.Transparent))
                        g.FillRectangle(hb, DrawRect);
                    g.DrawRectangle(DrawPen, DrawRect);
                    g.DrawString("?", DrawFont, ForeBrush, DrawRect, CenterFormat);
                }

                if (Orientation == enumOrientations.Right || Orientation == enumOrientations.Horizontal)
                    g.DrawLine(DrawPen, 0, Center.Y, DrawRect.Left, Center.Y);
                if (Orientation == enumOrientations.Left || Orientation == enumOrientations.Horizontal)
                    g.DrawLine(DrawPen, DrawRect.Right, Center.Y, Width - 1, Center.Y);
                if (Orientation == enumOrientations.Down || Orientation == enumOrientations.Vertical)
                    g.DrawLine(DrawPen, Center.Y, 0, Center.Y, DrawRect.Top);
                if (Orientation == enumOrientations.Up || Orientation == enumOrientations.Vertical)
                    g.DrawLine(DrawPen, Center.X,DrawRect.Bottom, Center.X, Height - 1);
            }
        }

        /// <summary>
        /// Draw the line text
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextLabel_Paint(object sender, PaintEventArgs e)
        {
            if (DisplayParameters.Names)
                e.Graphics.DrawString(this.Name, SystemFonts.CaptionFont, Brushes.Aqua, PointF.Empty);
        }
        #endregion
    }
}
